import { createAsyncThunk, createSlice, createSelector, createEntityAdapter } from "@reduxjs/toolkit";
import { client } from '../../api/client'

//const initialState = {
//  posts: [],
//  status: "idle",
//  error: null
//}

const postsAdapter = createEntityAdapter({
  sortComparer: (a, b) => b.date.localeCompare(a.date)
})

const initialState = postsAdapter.getInitialState({
  status: 'idle',
  error: null
})

export const fetchPosts = createAsyncThunk('posts/fetchPosts', async () => {
  const response = await client.get('/fakeApi/posts')
  return response.data
})

export const addNewPost = createAsyncThunk("posts/addNewPost", async (initialPost) => {
  const response = await client.post('/fakeApi/posts', initialPost);
  return response.data
})

const postsSlice = createSlice({
  name: "posts",
  initialState,
  reducers: {
    //postAdd: {
    //  reducer(state, action) {
    //    state.posts.push(action.payload)
    //  },
    //  prepare(title, content, authorId) {
    //    return {
    //      payload: {
    //        id: nanoid(),
    //        date: new Date().toISOString(),
    //        title,
    //        content,
    //        authorId: authorId,
    //      }
    //    }
    //  }
    //},
    postUpdate: (state, action) => {
      const {id, title, content} = action.payload;
      //const existingPost = state.posts.find(post => post.id === id)
      const existingPost = state.entities[id]
      if (existingPost) {
        existingPost.title = title
        existingPost.content = content
      }
    },
    reactionAdded: (state, action) => {
      const {id, reaction} = action.payload;
      //const existingPost = state.posts.find(post => post.id === id);
      const existingPost = state.entities[id]
      if (existingPost) {
        if (existingPost.reactions[reaction]){
          existingPost.reactions[reaction]++;
        }else{
          existingPost.reactions[reaction] = 1;
        }
      }
    }
  },
  extraReducers(builder) {
    builder
      .addCase(fetchPosts.pending, (state, action) => {
        state.status = "loading"
      })
      .addCase(fetchPosts.fulfilled, (state, action) => {
        state.status = "successed"
        //state.posts = state.posts.concat(action.payload)
        postsAdapter.upsertMany(state, action.payload)
      })
      .addCase(fetchPosts.rejected, (state, action) => {
        state.status = "failed"
        state.error = action.error.message
      })
      .addCase(addNewPost.fulfilled, postsAdapter.addOne)
  }
})

export const { postAdd, postUpdate, reactionAdded } = postsSlice.actions;

export default postsSlice.reducer;

//export const selectAllPost = state => state.posts.posts;
//export const selectPostById = (state, postId) => state.posts.posts.find(post => post.id === postId);

export const {
  selectAll: selectAllPosts,
  selectById: selectPostById,
  selectIds: selectPostIds
} = postsAdapter.getSelectors(state => state.posts)

// memoization
export const selectPostsByAuthor = createSelector(
  [selectAllPosts, (state, authorId) => authorId],
  (posts, authorId) => posts.filter(post => post.user === authorId)
)